<template>
  <el-select
    :value="value"
    @input="handleInput"
    @change="handleChange"
    :placeholder="placeholder"
    :size="size"
    :multiple="multiple"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :allow-create="allowCreate"
    :default-first-option="defaultFirstOption"
    :reserve-keyword="reserveKeyword"
    :no-match-text="noMatchText"
    :no-data-text="noDataText"
    :popper-class="popperClass"
    :loading="loading"
    :loading-text="loadingText"
    :style="{ width: width }"
    :class="customClass"
    :collapse-tags="collapseTags"
    :multiple-limit="multipleLimit"
    :name="name"
    :autocomplete="autocomplete"
    @visible-change="handleVisibleChange"
    @remove-tag="handleRemoveTag"
    @clear="handleClear"
  >
    <el-option
      v-for="item in options"
      :key="getOptionKey(item)"
      :label="getOptionLabel(item)"
      :value="getOptionValue(item)"
      :disabled="getOptionDisabled(item)"
    >
      <slot name="option" :item="item">
        {{ getOptionLabel(item) }}
      </slot>
    </el-option>
    
    <!-- 自定义选项组 -->
    <template v-if="hasGroups">
      <el-option-group
        v-for="group in groupedOptions"
        :key="group.label"
        :label="group.label"
        :disabled="group.disabled"
      >
        <el-option
          v-for="item in group.options"
          :key="getOptionKey(item)"
          :label="getOptionLabel(item)"
          :value="getOptionValue(item)"
          :disabled="getOptionDisabled(item)"
        >
          <slot name="option" :item="item">
            {{ getOptionLabel(item) }}
          </slot>
        </el-option>
      </el-option-group>
    </template>
  </el-select>
</template>

<script setup>
import { computed, defineProps, defineEmits } from '@vue/composition-api'

// 定义 Props
const props = defineProps({
  value: {
    type: [String, Number, Array, Boolean, Object],
    default: null
  },
  // 双向绑定的值
  modelValue: {
    type: [String, Number, Array, Boolean, Object],
    default: null
  },
  // 选项数组
  options: {
    type: Array,
    default: () => []
  },
  // 选项配置
  optionProps: {
    type: Object,
    default: () => ({
      label: 'label',
      value: 'value',
      disabled: 'disabled',
      key: 'value'
    })
  },
  // 宽度
  width: {
    type: String,
    default: '100%'
  },
  // 尺寸
  size: {
    type: String,
    default: 'small',
    validator: value => ['large', 'medium', 'small', 'mini'].includes(value)
  },
  // 占位符
  placeholder: {
    type: String,
    default: '请选择'
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false
  },
  // 是否可清空
  clearable: {
    type: Boolean,
    default: true
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否可搜索
  filterable: {
    type: Boolean,
    default: false
  },
  // 是否允许用户创建新条目
  allowCreate: {
    type: Boolean,
    default: false
  },
  // 在输入框按下回车，选择第一个匹配项
  defaultFirstOption: {
    type: Boolean,
    default: false
  },
  // 多选时是否将选中值按文字的形式展示
  collapseTags: {
    type: Boolean,
    default: false
  },
  // 多选时用户最多可以选择的项目数，为 0 则不限制
  multipleLimit: {
    type: Number,
    default: 0
  },
  // select input 的 name 属性
  name: {
    type: String,
    default: ''
  },
  // select input 的 autocomplete 属性
  autocomplete: {
    type: String,
    default: 'off'
  },
  // 在多选且可搜索时，是否在选中一个选项后保留当前的搜索关键词
  reserveKeyword: {
    type: Boolean,
    default: false
  },
  // 搜索条件无匹配时显示的文字
  noMatchText: {
    type: String,
    default: '无匹配数据'
  },
  // 选项为空时显示的文字
  noDataText: {
    type: String,
    default: '无数据'
  },
  // Select 下拉框的类名
  popperClass: {
    type: String,
    default: ''
  },
  // 是否正在从远程获取数据
  loading: {
    type: Boolean,
    default: false
  },
  // 远程加载时显示的文字
  loadingText: {
    type: String,
    default: '加载中'
  },
  // 自定义类名
  customClass: {
    type: String,
    default: ''
  },
  // 分组选项
  groupedOptions: {
    type: Array,
    default: () => []
  }
})

// 定义 Emits
const emit = defineEmits([
  'update:modelValue',
  'change',
  'visible-change',
  'remove-tag',
  'clear',
  'blur',
  'focus',
  'input'
])

// 计算属性
const hasGroups = computed(() => {
  return props.groupedOptions && props.groupedOptions.length > 0
})

// 方法
const getOptionKey = (item) => {
  return item[props.optionProps.key] || item[props.optionProps.value]
}

const getOptionLabel = (item) => {
  return item[props.optionProps.label]
}

const getOptionValue = (item) => {
  return item[props.optionProps.value]
}

const getOptionDisabled = (item) => {
  return item[props.optionProps.disabled] || false
}

const handleInput = (val) => {
  emit('input', val)
}

const handleChange = (value) => {
  emit('change', value)
}

const handleVisibleChange = (visible) => {
  emit('visible-change', visible)
}

const handleRemoveTag = (value) => {
  emit('remove-tag', value)
}

const handleClear = () => {
  emit('clear')
}
</script>

<style scoped>
/* 可以在这里添加自定义样式 */
</style> 